<template>
  <div :style="styleObj">
    <div class="Box">
      <div class="Lbox" v-show="iconShow">
        <span class="demonstration">显示数据条数(条):</span>
        <el-slider
          v-model="dataPeriod"
          :min="1"
          :max="20"
          @change="sliderChange"
        ></el-slider>
      </div>
      <div class="Rbox">
        <el-tooltip content="选择" placement="top" effect="light">
          <i class="el-icon-setting Ricon" @click="IconClick"></i>
        </el-tooltip>
        <el-tooltip content="刷新" placement="top" effect="light">
          <i class="el-icon-refresh Ricon" @click="parseLineSetting(true)"></i>
        </el-tooltip>
      </div>
    </div>
    <v-chart :options="options" autoresize :key="key" />
  </div>
</template>

<script>
import store from "@/store/index.js";
import {
  setMessageCallback,
  publishMsg,
  removeMessageCallback,
  checkSpecialId,
} from "@/mqtt";
import { SCADA_MSG } from "@/mqtt/msg.js";
export default {
  name: "WidgetBarStackchart",
  components: {},
  props: {
    value: Object,
    ispreview: Boolean,
    widgetIndex: Number,
    pageId: String,
  },
  data() {
    return {
      timer: [],
      data: [[], [], [], [], []],
      options: {
        grid: {},
        legend: {
          textStyle: {
            color: "#fff",
          },
        },
        xAxis: {
          type: "category",
          data: [],
          axisLabel: {
            show: true,
            textStyle: {
              color: "#fff",
            },
          },
        },
        yAxis: {
          type: "value",
          data: [],
          axisLabel: {
            show: true,
            textStyle: {
              color: "#fff",
            },
          },
        },
        series: [
          {
            data: [],
            name: "",
            type: "bar",
            barGap: "0%",
            itemStyle: {
              normal: {
                color: [],
                barBorderRadius: null,
              },
            },
          },
          {
            data: [],
            name: "",
            type: "bar",
            barGap: "0%",
            itemStyle: {
              normal: {
                color: [],
                barBorderRadius: null,
              },
            },
          },
          {
            data: [],
            name: "",
            type: "bar",
            barGap: "0%",
            itemStyle: {
              normal: {
                color: [],
                barBorderRadius: null,
              },
            },
          },
          {
            data: [],
            name: "",
            type: "bar",
            barGap: "0%",
            itemStyle: {
              normal: {
                color: [],
                barBorderRadius: null,
              },
            },
          },
          {
            data: [],
            name: "",
            type: "bar",
            barGap: "0%",
            itemStyle: {
              normal: {
                color: [],
                barBorderRadius: null,
              },
            },
          },
        ],
      },
      optionsStyle: {}, // 样式
      optionsData: {}, // 数据
      optionsSetup: {},
      flagInter: null,
      timeBarChart: {},
      timeBarChartCfg: [],
      dataSetting: [],
      legendName: [],
      xAxisList: [],
      dataPeriod: 5,
      iconShow: false,
      key: 1,
    };
  },
  computed: {
    styleObj() {
      return {
        position: this.ispreview ? "absolute" : "static",
        width: this.optionsStyle.width + "px",
        height: this.optionsStyle.height + "px",
        left: this.optionsStyle.left + "px",
        top: this.optionsStyle.top + "px",
        background: this.optionsSetup.background,
      };
    },
  },
  watch: {
    value: {
      handler(val) {
        this.xAxisList = [];
        this.optionsStyle = val.position;
        this.optionsData = val.data;
        this.optionsCollapse = val.setup;
        this.optionsSetup = val.setup;
        this.editorOptions();
      },
      deep: true,
    },
  },
  created() {
    this.initKey();
  },
  mounted() {
    setMessageCallback(this.onMsg);

    this.optionsStyle = this.value.position;
    this.optionsData = this.value.data;
    this.optionsCollapse = this.value.setup;
    this.optionsSetup = this.value.setup;
    this.editorOptions();
  },
  destroyed() {
    for (let i = 0; i < 5; i++) {
      if (this.timer[i] != null) {
        clearInterval(this.timer[i]);
        this.timer[i] = null;
      }
    }
    removeMessageCallback(this.onMsg);
  },
  methods: {
    IconClick() {
      this.iconShow = !this.iconShow;
    },
    sliderChange(val) {
      let msg = {
        webMsgType: 1022,
        funCode: 6,
        data: {
          id: this.pageId,
          widgetIndex: this.widgetIndex,
          setup: { dataPeriod: val },
        },
      };
      publishMsg(msg);
      store.commit("updateWidget", msg.data);
      this.parseLineSetting(true);
      // this.restartInterval();
    },
    initKey() {
      this.key = Math.trunc(Math.random() * 1000);
    },
    restartInterval() {
      const optionsSetup = this.optionsSetup;
      for (let i = 0; i < 5; i++) {
        if (this.timer[i] != null) {
          clearInterval(this.timer[i]);
          this.timer[i] = null;
        }

        this.timer[i] = setInterval(() => {
          // if (this.dataSetting.length > 0) {
          let dataId = this.dataSetting[i].dataId;
          let dataType = this.dataSetting[i].dataSetNameId;
          if (dataType != "" && dataId != "") {
            if (this.timeBarChart.hasOwnProperty(dataId)) {
              let datas = this.timeBarChart[dataId];
              // console.log(datas, "datas");
              if (datas.length > this.dataPeriod) {
                datas = datas.slice(-this.dataPeriod);
              }
              this.data[i] = [];
              let xData = [];
              for (let j = 0; j < datas.length; j++) {
                this.data[i].push(datas[j][1]);
                // + Math.random() * 5 + 3
                let datatime = datas[j][0].slice(
                  0,
                  datas[j][0].lastIndexOf(".")
                );
                xData.push(datatime);
              }

              if (optionsSetup.verticalShow) {
                this.options.xAxis.data = [];
                this.options.yAxis.data = xData;
                this.options.xAxis.type = "value";
                this.options.yAxis.type = "category";
              } else {
                this.options.xAxis.data = xData;
                this.options.yAxis.data = [];
                this.options.xAxis.type = "category";
                this.options.yAxis.type = "value";
              }
              this.options.series[i].data = this.data[i];
            }
          } else {
            this.options.series[i].data = [];
            clearInterval(this.timer[i]);
            this.timer[i] = null;
          }
          // }
        }, 100);
      }
    },
    // 修改图标options属性
    editorOptions() {
      this.dataPeriod = this.value.setup.dataPeriod;
      this.setOptionsTitle();
      this.setOptionsX();
      this.setOptionsY();
      this.setOptionsTooltip();
      this.setOptionsMargin();
      this.setOptionsLegend();
      // this.setOptionsData();
      this.parseLineSetting(true);
      this.restartInterval();
    },
    // 标题修改
    setOptionsTitle() {
      const optionsSetup = this.optionsSetup;
      const title = {};
      title.text = optionsSetup.titleText;
      title.show = optionsSetup.isNoTitle;
      title.left = optionsSetup.textAlign;
      title.textStyle = {
        color: optionsSetup.textColor,
        fontSize: optionsSetup.textFontSize,
        fontWeight: optionsSetup.textFontWeight,
      };
      title.subtext = optionsSetup.subText;
      title.subtextStyle = {
        color: optionsSetup.subTextColor,
        fontWeight: optionsSetup.subTextFontWeight,
        fontSize: optionsSetup.subTextFontSize,
      };
      this.options.title = title;
    },
    // X轴设置
    setOptionsX() {
      const optionsSetup = this.optionsSetup;
      const xAxis = {
        // boundaryGap: ["20%", "20%"],
        type: "time",
        // 坐标轴是否显示
        show: optionsSetup.hideX,
        // 坐标轴名称
        name: optionsSetup.xName,
        nameTextStyle: {
          color: optionsSetup.xNameColor,
          fontSize: optionsSetup.xNameFontSize,
        },
        // 轴反转
        inverse: optionsSetup.reversalX,
        axisLabel: {
          show: true,
          formatter: function (val) {
            let now = new Date(val);
            let hour = now.getHours();
            let min = now.getMinutes();
            if (hour < 10) {
              hour = "0" + hour;
            }
            if (min < 10) {
              min = "0" + min;
            }
            return (
              [now.getMonth() + 1, now.getDate()].join("-") +
              " " +
              [hour, min].join(":")
            );
          },
          // 文字间隔
          interval: optionsSetup.textInterval,
          // 文字角度
          rotate: optionsSetup.textAngleX,
          textStyle: {
            // 坐标文字颜色
            color: optionsSetup.Xcolor,
            fontSize: optionsSetup.fontSizeX,
          },
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: optionsSetup.lineColorX,
          },
        },
        splitLine: {
          show: optionsSetup.isShowSplitLineX,
          lineStyle: {
            color: optionsSetup.splitLineColorX,
          },
        },
      };
      this.options.xAxis = xAxis;
    },
    // Y轴设置
    setOptionsY() {
      const optionsSetup = this.optionsSetup;
      const yAxis = {
        type: "value",
        // 坐标轴是否显示
        show: optionsSetup.isShowY,
        // 坐标轴名称
        name: optionsSetup.textNameY,
        nameTextStyle: {
          color: optionsSetup.NameColorY,
          fontSize: optionsSetup.NameFontSizeY,
        },
        // y轴反转
        inverse: optionsSetup.reversalY,
        axisLabel: {
          show: true,
          // 文字角度
          rotate: optionsSetup.textAngleY,
          textStyle: {
            // 坐标文字颜色
            color: optionsSetup.colorY,
            fontSize: optionsSetup.fontSizeY,
          },
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: optionsSetup.lineColorY,
          },
        },
        splitLine: {
          show: optionsSetup.isShowSplitLineY,
          lineStyle: {
            color: optionsSetup.splitLineColorY,
          },
        },
      };
      this.options.yAxis = yAxis;
    },
    // tooltip 提示语设置，鼠标放置显示
    setOptionsTooltip() {
      const optionsSetup = this.optionsSetup;
      const tooltip = {
        trigger: "item",
        show: true,
        textStyle: {
          color: optionsSetup.lineColor,
          fontSize: optionsSetup.tipsFontSize,
        },
      };
      this.options.tooltip = tooltip;
    },
    // 边距设置
    setOptionsMargin() {
      const optionsSetup = this.optionsSetup;
      const grid = {
        left: optionsSetup.marginLeft,
        right: optionsSetup.marginRight,
        bottom: optionsSetup.marginBottom,
        top: optionsSetup.marginTop,
        containLabel: true,
      };
      this.options.grid = grid;
    },
    // 图例操作 legend
    setOptionsLegend() {
      const optionsSetup = this.optionsSetup;
      const legend = this.options.legend;
      legend.show = optionsSetup.isShowLegend;
      legend.left = optionsSetup.lateralPosition;
      legend.top = optionsSetup.longitudinalPosition;
      legend.bottom = optionsSetup.longitudinalPosition;
      legend.orient = optionsSetup.layoutFront;
      legend.textStyle = {
        color: optionsSetup.lengedColor,
        fontSize: optionsSetup.lengedFontSize,
      };
      legend.itemWidth = optionsSetup.lengedWidth;
    },
    // 图例名称设置
    setOptionsLegendName(name) {
      const optionsSetup = this.optionsSetup;
      const series = this.options.series;
      const legendName = optionsSetup.legendName;
      // 图例没有手动写则显示原值，写了则显示新值
      if (null == legendName || legendName == "") {
        for (let i = 0; i < name.length; i++) {
          series[i].name = name[i];
        }
        this.options.legend["data"] = name;
      } else {
        const arr = legendName.split("|");
        for (let i = 0; i < arr.length; i++) {
          series[i].name = arr[i];
        }
        this.options.legend["data"] = arr;
      }
    },
    // 数据解析
    parseLineSetting(force) {
      if (this.optionsData.dataType === "dynamicData") {
        if (this.optionsData.dynamicData.hasOwnProperty("chartProperties")) {
          this.dataSetting = this.optionsData.dynamicData.chartProperties;
          this.legendName = [];
          const optionsSetup = this.optionsSetup;
          //颜色
          const customColor = optionsSetup.customColor;
          for (let i = 0; i < this.dataSetting.length; i++) {
            this.options.series[i].data = [];
            this.options.series[i].itemStyle.normal.color = [];
            this.options.series[i].itemStyle.normal.barBorderRadius = null;
            let el = this.dataSetting[i];
            let dataId = el.dataId;
            let dataType = el.dataSetNameId;
            if (dataType != "" && dataId != "") {
              if (force) {
                this.reqDataList(dataType, dataId);
              } else {
                if (!this.timeBarChart.hasOwnProperty(dataId)) {
                  this.reqDataList(dataType, dataId);
                }
              }
              this.options.series[i].itemStyle.normal.color.push(
                customColor[i].color
              );
              this.options.series[i].itemStyle.normal.barBorderRadius =
                optionsSetup.radius;
              this.options.series[i].stack = this.getStackStyle();
              this.options.series[i].barWidth = optionsSetup.maxWidth;
            }
          }
        }
      }
    },
    checkDataListIsExist(dataId) {
      if (store.state.timeBarChart.hasOwnProperty(dataId)) {
        return true;
      } else {
        return false;
      }
    },
    reqDataList(dataType, dataId) {
      let msg = {
        webMsgType: 1020,
        funCode: 1,
      };
      const optionsSetup = this.optionsSetup;
      let obj = {};
      this.$set(obj, "id", dataId);
      switch (dataType) {
        case "yc":
          this.$set(obj, "from", "data-yc");
          break;
        case "ym":
          this.$set(obj, "from", "data-ym");
          break;
        case "task":
          this.$set(obj, "from", "data-task");
          break;
        default:
          return;
      }
      this.$set(obj, "count", this.dataPeriod);
      msg.data = obj;
      publishMsg(msg);
    },

    //去重
    setUnique(arr) {
      let newArr = [];
      arr.forEach((item) => {
        return newArr.includes(item) ? "" : newArr.push(item);
      });
      return newArr;
    },
    GetDateStr(days) {
      var date = new Date();
      // date.setDate(date.getDate() + days); //获取AddDayCount天后的日期
      date.setHours(date.getHours() - days); //获取AddDayCount小时的日期
      var Y = date.getFullYear();
      var MM = date.getMonth() + 1;
      var M = ""; //获取当前月份的日期
      if (MM >= 1 && MM <= 9) {
        M = "0" + MM;
      }
      var D = date.getDate() >= 10 ? date.getDate() : "0" + date.getDate();
      var H = date.getHours() >= 10 ? date.getHours() : "0" + date.getHours(); //获取系统时间
      var m =
        date.getMinutes() >= 10 ? date.getMinutes() : "0" + date.getMinutes(); //分
      var s =
        date.getSeconds() >= 10 ? date.getSeconds() : "0" + date.getSeconds(); //秒
      return Y + "-" + M + "-" + D + " " + H + ":" + m + ":" + s;
    },
    //获取堆叠样式
    getStackStyle() {
      const optionsSetup = this.optionsSetup;
      let style = "";
      if (optionsSetup.stackStyle == "upDown") {
        style = "total";
      }
      return style;
    },
    //静态数据
    staticDataFn(val) {
      const optionsSetup = this.optionsSetup;
      //颜色
      const customColor = optionsSetup.customColor;
      const arrColor = [];
      for (let i = 0; i < customColor.length; i++) {
        arrColor.push(customColor[i].color);
      }
      //数据
      const series = [];
      let xAxisList = [];
      let yAxisList = [];
      const legendName = [];
      for (const i in val) {
        xAxisList[i] = val[i].axis;
        yAxisList[i] = val[i].name;
      }
      xAxisList = this.setUnique(xAxisList);
      yAxisList = this.setUnique(yAxisList);
      for (const i in yAxisList) {
        const data = new Array(xAxisList.length).fill(0);
        for (const j in xAxisList) {
          for (const k in val) {
            if (val[k].name == yAxisList[i]) {
              if (val[k].axis == xAxisList[j]) {
                data[j] = val[k].data;
              }
            }
          }
        }
        series.push({
          name: yAxisList[i],
          type: "bar",
          data: data,
          barGap: "0%",
          stack: this.getStackStyle(),
          barWidth: optionsSetup.maxWidth,
          label: {
            show: optionsSetup.isShow,
            position: "top",
            distance: 10,
            fontSize: optionsSetup.fontSize,
            color: optionsSetup.subTextColor,
            fontWeight: optionsSetup.fontWeight,
          },
          //颜色，圆角属性
          itemStyle: {
            normal: {
              color: arrColor[i],
              barBorderRadius: optionsSetup.radius,
            },
          },
        });
        legendName.push(yAxisList[i]);
      }
      this.options.series = series;
      if (optionsSetup.verticalShow) {
        this.options.xAxis.data = [];
        this.options.yAxis.data = xAxisList;
        this.options.xAxis.type = "value";
        this.options.yAxis.type = "category";
      } else {
        this.options.xAxis.data = xAxisList;
        this.options.yAxis.data = [];
        this.options.xAxis.type = "category";
        this.options.yAxis.type = "value";
      }
      this.options.legend["data"] = legendName;
      this.setOptionsLegendName(legendName);
    },
    isMyData(id) {
      let bHasId = false;
      for (let i = 0; i < this.dataSetting.length; i++) {
        if (this.dataSetting[i].dataId == id) {
          bHasId = true;
          break;
        }
      }
      return bHasId;
    },
    //添加折叠柱状图数据
    addTimeBarChartData(data) {
      if (!this.timeBarChart.hasOwnProperty(data.id)) {
        this.timeBarChart[data.id] = [];
      }
      this.timeBarChart[data.id].push(data.data.value);
    },
    //对折叠柱状图数据处理
    removeTimeBarChartData(cfg) {
      let id = cfg.id;
      if (this.timeBarChart.hasOwnProperty(id)) {
        let length = this.timeBarChart[id].length;
        let canRemoveCount = 0;
        if (length > cfg.dataPeriod) {
          canRemoveCount = length - cfg.dataPeriod;
          this.timeBarChart[id].splice(0, canRemoveCount);
        }
      }
    },
    onMsg(topic, msg) {
      switch (msg.webMsgType) {
        case SCADA_MSG.scada_param_dashboard:
          {
            if (msg.funCode == 6) {
              if (checkSpecialId(msg)) {
                console.log("设置显示数据周期个数成功！");
              }
            }
          }
          break;
        case SCADA_MSG.scada_param_data:
          {
            if (msg.funCode == 1) {
              if (msg.retCode != 0) {
                return this.$message.error(msg.retMsg);
              } else {
                let data = msg.data;
                let dataId = data.id;
                let dataList = data.data;

                let isReq = this.isMyData(dataId);
                if (isReq) {
                  this.timeBarChart[dataId] = [];
                  this.timeBarChartCfg = [];
                  this.timeBarChartCfg.push({
                    id: data.id,
                    name: data.name,
                    unit: data.unit,
                  });
                  for (let k = 0; k < this.timeBarChartCfg.length; k++) {
                    if (this.timeBarChartCfg[k].id == dataId) {
                      this.options.yAxis.name = this.timeBarChartCfg[k].unit;
                      this.legendName.push(this.timeBarChartCfg[k].name);
                    }
                  }
                  this.setOptionsLegendName(this.legendName);
                  for (let i = 0; i < dataList.length; i++) {
                    let obj = {};
                    obj.id = dataId;
                    obj.data = {};
                    obj.data.value = [];
                    let datetime = dataList[i].datetime;
                    obj.data.value.push(datetime);
                    obj.data.value.push(dataList[i].value);
                    this.addTimeBarChartData(obj);
                  }
                  let cfg = { id: dataId, dataPeriod: this.dataPeriod };
                  this.removeTimeBarChartData(cfg);
                }
              }
            }
          }
          break;
        case SCADA_MSG.scada_param_yc:
          {
            switch (msg.funCode) {
              case 2:
                {
                  let dataList = msg.data;
                  for (let i = 0; i < dataList.length; i++) {
                    let data = dataList[i];
                    let dataId = data.id;
                    let value = data.value;
                    let datetime = data.update_time;
                    if (this.timeBarChart.hasOwnProperty(dataId)) {
                      let obj = {};
                      obj.id = dataId;
                      obj.data = {};
                      obj.data.value = [];
                      obj.data.value.push(datetime);
                      obj.data.value.push(value);
                      this.addTimeBarChartData(obj);
                    }
                    if (this.isMyData(dataId)) {
                      let cfg = { id: dataId, dataPeriod: this.dataPeriod };
                      this.removeTimeBarChartData(cfg);
                    }
                  }
                }
                break;
            }
          }
          break;
        case SCADA_MSG.scada_param_ym:
          {
            switch (msg.funCode) {
              case 2:
                {
                  let dataList = msg.data;
                  for (let i = 0; i < dataList.length; i++) {
                    let data = dataList[i];
                    let dataId = data.id;
                    let value = data.value;
                    let datetime = data.update_time;
                    if (this.timeBarChart.hasOwnProperty(dataId)) {
                      let obj = {};
                      obj.id = dataId;
                      obj.data = {};
                      obj.data.value = [];
                      obj.data.value.push(datetime);
                      obj.data.value.push(value);
                      this.addTimeBarChartData(obj);
                    }
                    if (this.isMyData(dataId)) {
                      let cfg = { id: dataId, dataPeriod: this.dataPeriod };
                      this.removeTimeBarChartData(cfg);
                    }
                  }
                }
                break;
            }
          }
          break;
        case SCADA_MSG.scada_param_task:
          {
            switch (msg.funCode) {
              case 4:
                {
                  let data = msg.data;
                  let dataId = data.id;
                  let value = data.value;
                  let datetime = data.update_time;
                  if (this.timeBarChart.hasOwnProperty(dataId)) {
                    let obj = {};
                    obj.id = dataId;
                    obj.data = {};
                    obj.data.value = [];
                    obj.data.value.push(datetime);
                    obj.data.value.push(value);
                    this.addTimeBarChartData(obj);
                  }
                  if (this.isMyData(dataId)) {
                    let cfg = { id: dataId, dataPeriod: this.dataPeriod };
                    this.removeTimeBarChartData(cfg);
                  }
                }
                break;
            }
          }
          break;
        default:
          break;
      }
    },
  },
};
</script>

<style scoped lang="scss">
.Box {
  display: flex;
  align-items: center;
  width: 90%;
  position: relative;

  .Lbox {
    display: flex;
    flex: 1;
    height: 30px;
    margin-top: -30px;

    .demonstration {
      width: 150px;
      line-height: 36px;
      margin-right: 20px;
    }

    .el-slider {
      flex: 1;

      ::v-deep .el-slider__runway {
        height: 5px;
        background-color: #0099ff;
      }
    }
  }

  .Rbox {
    position: absolute;
    top: -20px;
    right: -50px;
    width: 50px;
    display: flex;

    i {
      cursor: pointer;
      color: #0099ff;
      margin: 0 5px;
    }
  }
}

.echarts {
  width: 100%;
  // height: calc(100% - 30px);
  height: 100%;
  overflow: hidden;
}
</style>
